/** * <copyright> * * Copyright (c) 2011 Christian Kerl * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Christian Kerl - Initial API and implementation * * </copyright> */ package org.eclipselab.emf.codegen.protobuf; import java.io.File; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.Collections; import org.eclipse.core.runtime.Path; import org.eclipse.emf.codegen.ecore.generator.GeneratorAdapterFactory; import org.eclipse.emf.codegen.ecore.genmodel.GenModel; import org.eclipse.emf.codegen.ecore.genmodel.GenPackage; import org.eclipse.emf.codegen.ecore.genmodel.generator.GenBaseGeneratorAdapter; import org.eclipse.emf.common.util.BasicDiagnostic; import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.common.util.Monitor; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.plugin.EcorePlugin; import org.eclipselab.emf.codegen.protobuf.annotations.EPackageAnnotation; import org.eclipselab.emf.codegen.protobuf.internal.ProtobufGeneratorPlugin; import org.eclipselab.emf.codegen.protobuf.template.GenerateProtobufUtilities; import org.eclipselab.emf.ecore.protobuf.mapping.DefaultNamingStrategy; import org.eclipselab.emf.ecore.protobuf.mapping.MapperRegistry; import org.eclipselab.emf.ecore.protobuf.util.DescriptorDebugStringBuilder; import com.google.protobuf.DescriptorProtos; import com.google.protobuf.Descriptors; import com.google.protobuf.Descriptors.DescriptorValidationException; public class ProtobufPackageGeneratorAdapter extends GenBaseGeneratorAdapter { private ProtobufCompiler protobufCompiler; public ProtobufPackageGeneratorAdapter(GeneratorAdapterFactory generatorAdapterFactory) { this(generatorAdapterFactory, ProtobufGeneratorPlugin.getProtobufCompiler()); } public ProtobufPackageGeneratorAdapter(GeneratorAdapterFactory generatorAdapterFactory, ProtobufCompiler protobufCompiler) { super(generatorAdapterFactory); setProtobufCompiler(protobufCompiler); } public void setProtobufCompiler(ProtobufCompiler protobufCompiler) { this.protobufCompiler = protobufCompiler; } @Override public boolean canGenerate(Object object, Object projectType) { return MODEL_PROJECT_TYPE.equals(projectType) ? super.canGenerate(object, projectType) : false; } @Override protected Diagnostic generateModel(Object object, Monitor monitor) { boolean addedPluginDependecies = false; GenModel genModel = (GenModel) object; for(GenPackage genPackage : genModel.getGenPackages()) { EPackage ePackage = genPackage.getEcorePackage(); if(EPackageAnnotation.get(ePackage).generate()) { if(!addedPluginDependecies) { // TODO: maybe don't hardcode those plugin ids here genModel.getModelPluginVariables().add("org.eclipselab.emf.ecore.protobuf"); genModel.getModelPluginVariables().add("com.google.protobuf"); addedPluginDependecies = true; } DescriptorProtos.FileDescriptorSet.Builder files = DescriptorProtos.FileDescriptorSet.newBuilder(); MapperRegistry mappers = new MapperRegistry(new DefaultNamingStrategy()); mappers .find(ePackage) .map(ePackage, files); DescriptorProtos.FileDescriptorProto.Builder file = files.getFileBuilder(0); file.getOptionsBuilder() .setJavaPackage(genPackage.getReflectionPackageName()) .setJavaOuterClassname(genPackage.getPrefix() + "Protos"); Descriptors.FileDescriptor file2; try { file2 = Descriptors.FileDescriptor.buildFrom(file.build(), new Descriptors.FileDescriptor[0]); } catch (DescriptorValidationException e) { return BasicDiagnostic.toDiagnostic(e); } URI srcDirectory = toURI(genModel.getModelDirectory()); URI targetDirectory = srcDirectory.appendSegments(genPackage.getReflectionPackageName().split("\\.")); URI targetFile = targetDirectory.appendSegment(file.getPackage() + ".proto"); ensureContainerExists(targetDirectory, createMonitor(monitor, 1)); try { Writer writer = new OutputStreamWriter(createOutputStream(targetFile)); writer.write(new DescriptorDebugStringBuilder().build(file2)); writer.close(); } catch (Exception e) { return BasicDiagnostic.toDiagnostic(e); } srcDirectory = srcDirectory.appendSegment(""); String workingDirectory = toAbsoluteFilesystemPath(srcDirectory) + File.separator; String protoFile = toPlatformResourceURI(targetFile).deresolve(toPlatformResourceURI(srcDirectory)).toFileString(); if(protobufCompiler.isAvailable()) { try { protobufCompiler.invoke(workingDirectory, protoFile, workingDirectory); } catch(Throwable t) { return BasicDiagnostic.toDiagnostic(t); } } URI utilDirectory = toURI(genModel.getModelDirectory()).appendSegments(genPackage.getUtilitiesPackageName().split("\\.")); try { GenerateProtobufUtilities generateProtobufUtilities = new GenerateProtobufUtilities(genPackage, new File(toAbsoluteFilesystemPath(utilDirectory)), Collections.emptyList()); generateProtobufUtilities.generate(monitor); } catch (IOException e) { return BasicDiagnostic.toDiagnostic(e); } } } return Diagnostic.OK_INSTANCE; } private String toAbsoluteFilesystemPath(URI platformPath) { return EcorePlugin.getWorkspaceRoot().getFolder(new Path(platformPath.toFileString())).getLocation().toOSString(); } }